package org.geo.file.service;

import org.apache.commons.lang.StringUtils;
import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.FileUploadException;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
import org.apache.tomcat.util.http.fileupload.servlet.ServletRequestContext;
import org.geo.common.exception.BusinessException;
import org.geo.common.log.Log;
import org.geo.common.oss.OssClientHelper;
import org.geo.common.util.NumberUtil;
import org.geo.common.util.TimeUtil;
import org.geo.file.FileConstants;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * 文件上传Service
 *
 * @author ljy
 */
@Service
public class FileUploadService {
    /**
     * 文件名
     */
    private String filename;
    /**
     * 内容类型
     */
    private String contentType;
    /**
     * 字节输入流
     */
    private InputStream inputStream;
    /**
     * 文件大小
     */
    private long fileSize;

    /**
     * 上传头像文件
     *
     * @param request HttpServletRequest
     * @return 文件名
     */
    public String uploadAvatar(HttpServletRequest request) throws BusinessException {
        FileItem fileItem = parseUploadRequest(request, FileConstants.AVATAR_MAX_SIZE);
        if (fileItem != null) {
            checkFileInfo(fileItem);
        }
        String fileName = FileConstants.AVATAR_PREFIX + TimeUtil.getCurrentDate() + NumberUtil.randomInt(100) + FileConstants.AVATAR_SUFFIX_PNG;

        String fName = OssClientHelper.uploadAvatarFile(inputStream, fileSize, contentType, fileName);
        if (StringUtils.isBlank(fileName)) {
            throw new BusinessException("Upload Avatar Failed");
        }
        return fName;
    }

    /**
     * 检查文件信息
     *
     * @param fileItem FileItem
     */
    private void checkFileInfo(FileItem fileItem) throws BusinessException {
        // 此时的文件名包含了完整的路径，得注意加工一下
        String filename = fileItem.getName();

        int index = filename.lastIndexOf("\\");
        filename = filename.substring(index + 1, filename.length());
        //检查文件名是否为空
        if ("".equals(filename)) {
            throw new BusinessException("Filename Is Empty");
        }
        //检查文件大小是否合法
        fileSize = fileItem.getSize();
        if (fileSize <= 0) {
            throw new BusinessException("File Size Error");
        }
        //检查文件类型
        contentType = fileItem.getContentType();
        if (!FileConstants.AVATAR_SUFFIX_PNG.equals(contentType) || !FileConstants.AVATAR_SUFFIX_JPG.equals(contentType)) {
            throw new BusinessException("Illegal File Type");
        }
        try {
            inputStream = fileItem.getInputStream();
        } catch (IOException e) {
            throw new BusinessException("IO Exception");
        }
    }

    /**
     * 解析上传来的文件
     *
     * @param request           HttpServletRequest
     * @param uploadFileMaxSize 上传的文件的最大大小
     * @return FileItem
     */
    private FileItem parseUploadRequest(HttpServletRequest request, long uploadFileMaxSize) {
        DiskFileItemFactory diskFactory = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(diskFactory);
        // 设置允许上传的最大文件大小
        upload.setSizeMax(uploadFileMaxSize);
        // 解析HTTP请求消息头
        List<FileItem> fileItems = null;
        try {
            fileItems = upload.parseRequest((new ServletRequestContext(request)));

        } catch (FileUploadException e) {
            Log.e(e, "Parse Upload Request failed");
        }
        if (fileItems != null) {
            for (FileItem item : fileItems) {
                if (!item.isFormField()) {
                    return item;
                }
            }
        }
        return null;
    }
}
